/*
Copyright (C) 2011  Christoph Schnack, Berlin (Germany)

This file is part of Tribuit.

    Tribuit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Tribuit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tribuit.  If not, see <http://www.gnu.org/licenses/>.
*/

package VMTermClassSettingsDialog;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import GuiTools.*;
import Settings.*;
import Storage.*;

/**
 * @author Christoph Schnack
 *
 */
public class TermClassPanel extends JPanel{
	private JPanel panel,metaPanel,articleContent;
	private JComboBox tcCB;
	private DefaultComboBoxModel sortedTermClassKeys;
	private JButton deleteArticleBtn;
	
	private HashMap<String, TermClass> termClasses;
	private TermClass currentTermClass;
	
	private String editedLangName;
	private Settings SET;
	private Language LANG;
	private TribuitFrame vsdFrame;
	private VocabularyTermClassManagement vtcmDialog;
	
	/**
	 * 
	 * @param mainvoc 
	 * @param set
	 * @param parentFrame
	 * @param vteArg
	 * @param tcsArg term classes A or B 
	 * @param sortedTCKeysArg
	 */

	public TermClassPanel(Storage mainvoc, Settings set,VocabularyTermClassManagement vtcm, String langName, Vocabulary vteArg, HashMap<String,TermClass> tcsArg, Vector<String> sortedTCKeysArg){
		super();
		SET = set;
		LANG = SET.getLanguage();
		vtcmDialog = vtcm;
		vsdFrame = vtcmDialog.getFrame();
		termClasses = new HashMap<String,TermClass>();
		TermClass src;
		for(String key : tcsArg.keySet()){
			TermClass tc = new TermClass();
			src = tcsArg.get(key);
			if(!src.isEmpty()){
				for(String mKey : src.getKeys()){
					Vector<String> vec = null;
					if(src.getValues(mKey)!=null){
						vec = new Vector<String>();
						for(String val : src.getValues(mKey)){
							vec.add(val);
						}
					}
					tc.putElement(mKey,vec);
				}
				tc.setSortedKeys((Vector<String>)src.getSortedKeys().clone());
			}
			if(src.hasPrefix()){
				Vector<String> pVals = null;
				if(src.getPreFixVal()!=null){
					pVals = new Vector<String>(); 
					for(String val : src.getPreFixVal()){
						pVals.add(val);
					}
				}
				tc.setPreFix(src.getPreFixName(),pVals);
			}
			termClasses.put(key, tc);
		}
		sortedTermClassKeys = new DefaultComboBoxModel((Vector<String>) sortedTCKeysArg.clone());
		editedLangName = langName;
		
	//top panel A
		tcCB = new JComboBox(sortedTermClassKeys);
		tcCB.setPreferredSize(new Dimension(300,26));
		tcCB.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent arg0) {
				updateTermClass();
			}
		});
		JButton createTCButton = new JButton(LANG.getNew());
		createTCButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				SwingUtilities.invokeLater(new Runnable(){
					public void run(){
						String input = JOptionPane.showInputDialog(LANG.getNewTermClassName()+":");
						if(input!=null){
							input = input.trim();
							while(input.equals("") || !GuiTools.checkInput(input) || termClasses.containsKey(input)){
								if(input.equals("") || !GuiTools.checkInput(input)){
									GuiTools.showEmptyOrInvalidInputWarning(LANG, vsdFrame, LANG.getNewTermClassName());
								}
								if(termClasses.containsKey(input)){
									JOptionPane.showMessageDialog(vsdFrame, LANG.getTermClassAlreadyExists(),LANG.getError(), JOptionPane.ERROR_MESSAGE);
								}
								input = JOptionPane.showInputDialog(LANG.getNewTermClassName()+":",input);
								if(input == null) return;
								input = input.trim();
							}
							termClasses.put(input, new TermClass());
							sortedTermClassKeys.addElement(input);
							vtcmDialog.setChangesMade(true);
							tcCB.setSelectedIndex(0);
						}
					}
				});
			}
		});
		JButton editTCButton = new JButton(LANG.getEditName());
		editTCButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				String oldName =  (String) tcCB.getSelectedItem();
				String input = JOptionPane.showInputDialog(LANG.getEditTermClassName()+":", oldName);
				if(input!=null){
					input = input.trim();
					while(input.equals("") || !GuiTools.checkInput(input) || termClasses.containsKey(input)){
						if(input.equals("") || !GuiTools.checkInput(input)){
							GuiTools.showEmptyOrInvalidInputWarning(LANG, vsdFrame, LANG.getEditTermClassName());
						}
						if(termClasses.containsKey(input)){
							JOptionPane.showMessageDialog(vsdFrame, LANG.getTermClassAlreadyExists(),LANG.getError(), JOptionPane.ERROR_MESSAGE);
						}
						input = JOptionPane.showInputDialog(LANG.getEditTermClassName()+":",input);
						if(input == null) return;
					}
					TermClass tc = termClasses.get(oldName);
					termClasses.remove(oldName);
					sortedTermClassKeys.removeElement(oldName);
					termClasses.put(input, tc);
					sortedTermClassKeys.addElement(input);
					vtcmDialog.setChangesMade(true);
					tcCB.setSelectedIndex(0);
				}
			}
		});
		JButton rangeTCButton = new JButton(LANG.getRange());
		rangeTCButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				TCRangeDialog rd = new TCRangeDialog(LANG,vsdFrame,sortedTermClassKeys);
				if(!rd.isCanceled()){
					sortedTermClassKeys.removeAllElements();
					for(String s : rd.getNewRange()){
						sortedTermClassKeys.addElement(s);
					}
					vtcmDialog.setChangesMade(true);
				}
			}
		});
		JButton deleteTCButton = new JButton(LANG.getDelete());
		deleteTCButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(termClasses.keySet().size()==1){
					JOptionPane.showMessageDialog(vsdFrame,LANG.getOneTcMustRemain(),LANG.getAttention(),JOptionPane.WARNING_MESSAGE);
				}
				else{
					int answer = JOptionPane.showConfirmDialog(vsdFrame, LANG.getDeleteReally()+ " '"+((String)tcCB.getSelectedItem())+"' ?", LANG.getAttention(), JOptionPane.YES_NO_OPTION);
					if(answer == JOptionPane.YES_OPTION){
						String oldName = (String) tcCB.getSelectedItem();
						termClasses.remove(oldName);
						sortedTermClassKeys.removeElement(oldName);
						tcCB.setSelectedIndex(0);
						vtcmDialog.setChangesMade(true);
					}
				}
			}
		});
		JPanel tButtonPanel = new JPanel();
		tButtonPanel.add(createTCButton);
		tButtonPanel.add(editTCButton);
		tButtonPanel.add(rangeTCButton);
		tButtonPanel.add(deleteTCButton);
		tButtonPanel.setOpaque(false);
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new BoxLayout(topPanel,BoxLayout.Y_AXIS));
		topPanel.add(tcCB);
		topPanel.add(tButtonPanel);
		topPanel.setOpaque(false);
		
	//article
		JButton prefixBtn = new JButton(LANG.getEdit());
		prefixBtn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				EditElement ee;
				if(currentTermClass.hasPrefix()){
					ee = new EditElement(SET,vsdFrame,LANG.getEditArticle(),currentTermClass.getPreFixName(),currentTermClass.getPreFixVal());
				}
				else{
					ee = new EditElement(SET,vsdFrame,LANG.getEditArticle());
				}
				if(!ee.isCanceled()){
					currentTermClass.setPreFix(ee.getNewName(), ee.getNewValues());
					setArticle();
					vtcmDialog.setChangesMade(true);
					vsdFrame.pack();
					vsdFrame.repaint();
				}
			}
		});
		deleteArticleBtn = new JButton(LANG.getDelete());
		deleteArticleBtn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int ans = JOptionPane.showConfirmDialog(vsdFrame, LANG.getDeleteReally()+" "+LANG.getArticle()+"?", LANG.getAttention(), JOptionPane.WARNING_MESSAGE);
				if(ans!=JOptionPane.YES_OPTION) return;
				currentTermClass.setPreFix(null, null);
				setArticle();
				vtcmDialog.setChangesMade(true);
				vsdFrame.pack();
				vsdFrame.repaint();
			}
		});
		JPanel articleBtnPanel = new JPanel();
		articleBtnPanel.add(prefixBtn);
		articleBtnPanel.add(deleteArticleBtn);
		
		articleContent=new JPanel();
		JScrollPane articleJSP = new JScrollPane(articleContent);
		articleJSP.setPreferredSize(new Dimension(300,50));
		articleJSP.setBorder(null);
		
		JPanel articlePanel = new JPanel();
		articlePanel.setLayout(new GridBagLayout());
		GridBagConstraints artGbc = new GridBagConstraints();
		artGbc.anchor = GridBagConstraints.NORTHWEST;
		artGbc.gridy=0;
		articlePanel.add(articleJSP,artGbc);
		artGbc.gridy=1;
		articlePanel.add(articleBtnPanel,artGbc);
		articlePanel.setBorder(BorderFactory.createTitledBorder(LANG.getArticle()+":"));
		
	//meta panel
		metaPanel = new JPanel();
		metaPanel.setLayout(new BoxLayout(metaPanel,BoxLayout.Y_AXIS));
		JButton createMetaButton = new JButton(LANG.getAdd());
		createMetaButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				EditElement ee = new EditElement(SET,vsdFrame,LANG.getCreateMetaInformation());
				if(!ee.isCanceled()){
					if(!currentTermClass.getSortedKeys().contains(ee.getNewName())){
						currentTermClass.putElement(ee.getNewName(), ee.getNewValues());
						setMetas();
						vtcmDialog.setChangesMade(true);
						vsdFrame.pack();
						vsdFrame.repaint();
					}
					else{
						JOptionPane.showMessageDialog(vsdFrame,LANG.getMetaInformationAlreadyExists(),LANG.getError(),JOptionPane.ERROR_MESSAGE);
					}
				}
			}
		});
		JScrollPane metaJSP = new JScrollPane(metaPanel);
		metaJSP.setPreferredSize(new Dimension(300,110));
		metaJSP.getVerticalScrollBar().setUnitIncrement(50);
		
		JPanel mPanel = new JPanel();
		mPanel.setLayout(new BoxLayout(mPanel,BoxLayout.Y_AXIS));
		mPanel.add(metaJSP);
		mPanel.add(createMetaButton);
		mPanel.setBorder(BorderFactory.createTitledBorder(LANG.getMetainformation()+":"));
		
		JLabel label = new JLabel(editedLangName);
		label.setFont(new Font(Font.SANS_SERIF,Font.BOLD,20));
		label.setHorizontalAlignment(JLabel.CENTER);
		label.setPreferredSize(new Dimension(300,label.getPreferredSize().height));
		
		panel = this;
		//panel.setBackground(Color.gray);
		panel.setLayout(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		
		JPanel cp = new JPanel();
		cp.setLayout(new GridBagLayout());
		cp.setBackground(Color.lightGray);
		gbc.gridy=0;
		cp.add(topPanel,gbc);
		gbc.gridy=1;
		cp.add(articlePanel,gbc);
		gbc.gridy=2;
		cp.add(mPanel,gbc);
		
		gbc.gridy=0;
		gbc.fill=GridBagConstraints.NONE;
		gbc.anchor=GridBagConstraints.CENTER;
		panel.add(label,gbc);
		gbc.fill=GridBagConstraints.BOTH;
		gbc.anchor=GridBagConstraints.NORTHWEST;
		gbc.gridy=1;
		panel.add(cp,gbc);
		updateTermClass();
	}
	
	public void updateTermClass(){
		String selection = (String)tcCB.getSelectedItem();
		currentTermClass = termClasses.get(selection);
		setMetas();
		setArticle();
		vsdFrame.pack();
		vsdFrame.repaint();
	}
	
	public void setMetas(){
		metaPanel.removeAll();
		GridBagConstraints gbc = new GridBagConstraints();
		if(currentTermClass!=null){
			if(!currentTermClass.isEmpty()){
				int index = 0;
				for(String s : currentTermClass.getSortedKeys()){
					gbc.gridy++;
					metaPanel.add(new Element(index++,s,currentTermClass.getValues(s)),gbc);
				}
			}
		}
	}
	
	public void setArticle(){
		articleContent.removeAll();
		if(currentTermClass!=null){
			deleteArticleBtn.setEnabled(currentTermClass.hasPrefix());
			if(currentTermClass.hasPrefix()){
				String content;
				Vector<String> vals = currentTermClass.getPreFixVal();
				if(vals==null) content="TextField";
				else{
					StringBuffer sb = new StringBuffer();
					sb.append("ComboBox (");
					for(int i=0;i<vals.size();i++){
						sb.append(vals.elementAt(i));
						if(i!=vals.size()-1) sb.append(",");
					}
					sb.append(")");
					content = sb.toString();
				}
				articleContent.add(new JLabel(currentTermClass.getPreFixName()+": "+content));
			}
		}
	}
	
	
	
	class Element extends JPanel{
		String name;
		Vector<String> val;
		int number;
		public Element(int num, String nam, Vector<String> v){
			super();
			name=nam;
			val = v;
			number = num;
			JButton upButton = new JButton("up");
			upButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					Vector<String> tmp = currentTermClass.getSortedKeys();
					String old = tmp.elementAt(number-1);
					tmp.set(number-1, name);
					tmp.set(number, old);
					currentTermClass.setSortedKeys(tmp);
					setMetas();
					vtcmDialog.setChangesMade(true);
					vsdFrame.pack();
					vsdFrame.repaint();
				}
			});
			JButton downButton = new JButton("down");
			downButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					Vector<String> tmp = currentTermClass.getSortedKeys();
					String old = tmp.elementAt(number+1);
					tmp.set(number+1, name);
					tmp.set(number, old);
					currentTermClass.setSortedKeys(tmp);
					setMetas();
					vtcmDialog.setChangesMade(true);
					vsdFrame.pack();
					vsdFrame.repaint();
				}
			});
			if(number==0)upButton.setEnabled(false);
			if(number==currentTermClass.getSortedKeys().size()-1) downButton.setEnabled(false);
			JButton edtButton = new JButton(LANG.getEdit());
			edtButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					SwingUtilities.invokeLater(new Runnable(){
						public void run(){
							EditElement ee = new EditElement(SET,vsdFrame,LANG.getEditMeta(),name,val);
							if(!ee.isCanceled()){
								if(currentTermClass.hasKey(ee.getNewName())){
									int ans  = JOptionPane.showOptionDialog(vsdFrame,LANG.getOverwriteMetaInformation()+" "+ee.getNewName()+" ?",LANG.getError(),JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE,null,new String[]{LANG.getYes(),LANG.getNo()}, LANG.getYes());
									if(ans != JOptionPane.YES_OPTION){
										return;
									}
								}
								currentTermClass.removeElement(ee.getOldName());
								currentTermClass.putElement(ee.getNewName(),ee.getNewValues());
								setMetas();
								vtcmDialog.setChangesMade(true);
								vsdFrame.pack();
								vsdFrame.repaint();
							}
						}
					});
				}
			});
			JButton delButton = new JButton(LANG.getDelete());
			delButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					String[] opts= {LANG.getYes(),LANG.getNo()};
					int choice = JOptionPane.showOptionDialog(vsdFrame, LANG.getWarnDelAllMeta(), LANG.getAttention(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, opts, null);
					if(choice==JOptionPane.YES_OPTION){
						currentTermClass.deleteKey(name);
						vtcmDialog.setChangesMade(true);
						setMetas();
						vsdFrame.pack();
						vsdFrame.repaint();
					}
				}
			});
			JLabel nLabel = new JLabel(name+":");
			nLabel.setFont(new Font(Font.SERIF,Font.BOLD,14));
			JLabel tLabel = new JLabel("text-field");
			JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
			labelPanel.add(nLabel);
			labelPanel.add(tLabel);
			if(val!=null){
				StringBuffer sb = new StringBuffer();
				for(int i=0;i<val.size();i++){
					sb.append(val.elementAt(i));
					if(i<val.size()-1)sb.append(",");
				}
				tLabel.setText("combo-box: "+sb.toString());
			}
			tLabel.setFont(new Font(Font.SERIF,Font.PLAIN,14));
			JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
			buttonPanel.add(upButton);
			buttonPanel.add(downButton);
			buttonPanel.add(edtButton);
			buttonPanel.add(delButton);
			this.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.anchor=GridBagConstraints.NORTHWEST;
			gbc.fill = GridBagConstraints.BOTH;
			gbc.weightx = 1;
			this.add(labelPanel,gbc);
			gbc.gridy=1;
			this.add(buttonPanel,gbc);
			this.setBorder(BorderFactory.createLineBorder(Color.black));
		}
	}
	
	public HashMap<String, TermClass> getTermClasses(){
		return termClasses;
	}
	
	public Vector<String> getSortedTermClassKeys(){
		Vector<String> v = new Vector<String>();
		for(int i=0;i<sortedTermClassKeys.getSize();i++){
			v.add((String)sortedTermClassKeys.getElementAt(i));
		}
		return v;
	}
}
